package com.example.origin.demo.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("ShiftOptionDemo")
@RestController
public class ShiftOptionDemo {

    /**
     * 1(int):
     *   源码：00000000 00000000 00000000 00000001
     *   反码：与源码相同
     *   补码：与源码相同
     *
     * -1(int):
     *   源码：10000000 00000000 00000000 00000001
     *   反码：11111111 11111111 11111111 11111110
     *   补码：11111111 11111111 11111111 11111111
     *
     * << ：左移
     * >> : 有符号右移
     * >>> : 无符号右移
     *
     * 左移会将补码的所有比特位向左移动
     * 有符号右移将所有比特位移动后“空出来”的比特位会补符号位，负数补1，正数补0
     * 无符号右移移动后“空出来”的比特位会补0，不管是正数还是负数
     *
     * 编译器（可能不是全部的编译器）发现移动的位数等于或超过数值本身的位数后，会
     * 对这个移动的位数进行取模操作， 也就是说一个int型的变量x，x << 32 等价于 x << 1
     */
    @GetMapping("test")
    public void test() {

        /*
         * 结果：4
         *                 1补码
         * 00000000 00000000 00000000 00000001 = 1
         * 左移2位后的补码
         * 00000000 00000000 00000000 00000100 = 4
         */
        System.out.println(1 << 2);

        /*
         * 结果：-4
         *                -1补码
         * 11111111 11111111 11111111 11111111 = -1
         * 左移2位后的补码：
         * 11111111 11111111 11111111 11111100
         * 转换成原码：
         * 10000000 00000000 00000000 00000100 = -4
         */
        System.out.println(-1 << 2);

        /*
         * 结果：0
         *                  1补码
         * 00000000 00000000 00000000 00000001 = 1
         * 有符号右移2位后的补码：
         * 00000000 00000000 00000000 00000000 = 0
         */
        System.out.println(1 >> 2);

        /*
         * 结果：-1
         *                 -1补码
         * 11111111 11111111 11111111 11111111 = -1
         * 有符号右移2位后的补码：
         * 11111111111111111111111111111111111 = -1
         */
        System.out.println(-1 >> 2);

        /*
         * 结果：0
         *                  1补码
         * 00000000 00000000 00000000 00000001 = 1
         * 无符号右移2位后的补码：
         * 00000000 00000000 00000000 00000000 = 0
         */
        System.out.println(1 >>> 2);

        /*
         * 结果：1073741823
         *                 -1补码
         * 11111111 11111111 11111111 11111111 = -1
         * 无符号右移2位后的补码：
         * 00111111 11111111 11111111 11111111 = 1073741823
         * 这个时候负数就变成了正数
         */
        System.out.println(-1 >>> 2);

        //输出：1073741823
        System.out.println(0b00111111111111111111111111111111);

        /*
         * 11111111 11111111 11111111 11111111 = -1
         * 无符号右移一位后的结果：
         * 01111111 11111111 11111111 11111111 = 2147483647
         */
        System.out.println(-1 >>> 1);

        //输出：2147483647
        System.out.println(0b01111111111111111111111111111111);

    }
}
